package com.fowo.api.service.handleWork;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.entity.Product;
import com.fowo.api.entity.ScanShipment;
import com.fowo.api.mapper.ScanShipmentMapper;
import com.fowo.api.model.nav.sell.order.detail.NavSellOrderDetailItemVo;
import com.fowo.api.model.nav.sell.order.detail.NavSellOrderDetailSearchParamPo;
import com.fowo.api.model.scan.shipment.InspectGoodsVo;
import com.fowo.api.model.scan.shipment.ScanShipmentVo;
import com.fowo.api.service.NavSellOrderDetailService;
import com.fowo.api.service.impl.NavSellOrderServiceImpl;
import com.fowo.api.service.impl.ProductServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Service
@Slf4j
public class ScanShipmentAddService extends ServiceImpl<ScanShipmentMapper, ScanShipment> {

    @Resource
    protected NavSellOrderDetailService navSellOrderDetailService;
    @Resource
    private ProductServiceImpl productService;
    @Resource
    private NavSellOrderServiceImpl navSellOrderService;

    public ScanShipmentVo getVoByOrderId(String orderId,List<Long> deliveryLogisticsChannelInList){
        LambdaQueryWrapper<ScanShipment> queryWrapper = Wrappers.lambdaQuery(ScanShipment.class)
                .eq(ScanShipment::getOrderId, orderId)
                .or().eq(ScanShipment::getDeliveryTrackId, orderId)
                .or().eq(ScanShipment::getDeliveryWaybillId, orderId)
                .ne(ScanShipment::getType, "4")
                .eq(ScanShipment::getLogisticsOrderStatus, "2");
        if(CollectionUtil.isNotEmpty(deliveryLogisticsChannelInList)){
            queryWrapper.in(ScanShipment::getDeliveryLogisticsChannel, deliveryLogisticsChannelInList);
        }
        ScanShipment scanShipment = this.getOne(queryWrapper);
        if (scanShipment == null) {
            return null;
        }
        ScanShipmentVo vo = new ScanShipmentVo();
        BeanUtil.copyProperties(scanShipment,vo);
        NavSellOrderDetailSearchParamPo productSearchParamPo =
                new NavSellOrderDetailSearchParamPo();
        productSearchParamPo.setParentNavSellOrder(scanShipment.getId());
        productSearchParamPo.applySqlSegments();
        vo.setProduct(navSellOrderDetailService.search(productSearchParamPo));

        return vo;
    }

    /**
     * 验货
     * @param model
     */
    public void inspectGoods(InspectGoodsVo model){
        LambdaUpdateWrapper<ScanShipment> updateWrapper = Wrappers.lambdaUpdate(ScanShipment.class)
                .set(ScanShipment::getIsTest, "1");
        if(model.getIsInspectWeigh()){ //验货时称重
            updateWrapper
                    .set(ScanShipment::getDeliveryRealWeight,model.getDeliveryRealWeight())
                    .set(ScanShipment::getIsWeigh,"1");

            if(model.getIsCheckWeigh()){ //校验重量
                checkWeigh(model);

            }
            if(model.getIsSyncProduct()){ //同步到产品
                updateWeighToProduct(model);
            }
        }
        this.update(updateWrapper
                .eq(ScanShipment::getId,model.getId()));
    }

    public void weight(InspectGoodsVo model){
        Wrappers.lambdaUpdate(ScanShipment.class)
                .set(ScanShipment::getDeliveryRealWeight,model.getDeliveryRealWeight())
                .set(ScanShipment::getIsWeigh,"1")
                .eq(ScanShipment::getId,model.getId());

        if(model.getIsCheckWeigh()){ //校验重量
            checkWeigh(model);

        }
        if(model.getIsSyncProduct()){ //同步到产品
            updateWeighToProduct(model);
        }
        this.update(Wrappers.lambdaUpdate(ScanShipment.class)
                .set(ScanShipment::getDeliveryRealWeight,model.getDeliveryRealWeight())
                .set(ScanShipment::getIsWeigh,"1")
                .eq(ScanShipment::getId,model.getId()));
    }

    /**
     * 重量校验
     * @param model
     */
    public void checkWeigh(InspectGoodsVo model){
        String weightUnit = model.getDeliveryRealWeightUnit();
        model.getDeliveryThinkFeeWeightUnit();
        BigDecimal realWeight = model.getDeliveryRealWeight();
        BigDecimal thinkWeight = model.getDeliveryThinkWeight();
        BigDecimal thousand = new BigDecimal(1000);
        if(weightUnit.equals("g") && model.getDeliveryThinkFeeWeightUnit().equals("kg")){
            thinkWeight = thinkWeight.multiply(thousand);
        }
        if(weightUnit.equals("kg") && model.getDeliveryThinkFeeWeightUnit().equals("g")){
            thinkWeight = thinkWeight.divide(thinkWeight);
        }

        if(model.getDifferType().equals("1")){ //相差重量

            Assert.isFalse(realWeight.compareTo(thinkWeight.add(model.getAddWeigh())) == 1,"实重大于预估重量");
            Assert.isFalse(realWeight.compareTo(thinkWeight.subtract(model.getSubWeigh())) == -1,"实重小于预估重量");
        }else if(model.getDifferType().equals("2")){ //相差百分比
            BigDecimal add = thinkWeight.multiply(model.getAddWeigh());
            BigDecimal sub = thinkWeight.multiply(model.getSubWeigh());
            Assert.isFalse(realWeight.compareTo(thinkWeight.add(add)) == 1,"实重大于预估重量");
            Assert.isFalse(realWeight.compareTo(thinkWeight.subtract(sub)) == -1,"实重小于预估重量");
        }
    }

    /**
     * 同步至产品管理（产品毛重）
     * @param model
     */
    public void updateWeighToProduct(InspectGoodsVo model){
        final List<NavSellOrderDetailItemVo> detailItemVos = model.getProduct();
        final Long productId = detailItemVos.get(0).getProductId();
        productService.update(Wrappers.lambdaUpdate(Product.class)
                .set(Product::getProductGross,model.getDeliveryRealWeight())
                .eq(Product::getId,productId));
    }

    public void shipments(List<Long> ids) throws Exception {

        navSellOrderService.deliver(ids);
    }
}
